#ifndef LL1PARSER_HPP
#define LL1PARSER_HPP

#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#define END_SYMNOL "#"

struct define {
  std::string leftItem;
  std::vector<std::string> rightItem;
  int follow_idx;
};

class LL1Parser {
private:
  std::unordered_set<std::string> get_blank_set();
  void mark_follow_idx();
  bool can_be_blank(std::vector<std::string> right_item);

public:
  std::vector<define> defines;
  std::unordered_set<std::string> terminals;
  std::unordered_map<std::string, std::unordered_set<std::string>> first_set,
      follow_set;
  std::unordered_map<int, std::unordered_set<std::string>> select_set;
  std::unordered_set<std::string> blank_set;

  std::unordered_map<std::string, std::unordered_set<std::string>>
  get_first_set();
  std::unordered_map<std::string, std::unordered_set<std::string>>
  get_follow_set();
  std::unordered_map<int, std::unordered_set<std::string>> get_select_set();
  std::unordered_map<std::string, std::vector<std::string>> get_table();
};

#endif // !LL1PARSER_HPP
